home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 53142 / 53142.xpi / content / soaccount.js < prev    next >
Text File  |  2009-12-06  |  9KB  |  290 lines

  1. /*##########################################################################
  2.     Copyright 2009 Tim Reid
  3.  
  4.     This file is part of the Stack Overflow Reputation Display extension
  5.     for Mozilla Firefox.
  6.  
  7.     Stack Overflow Reputation Display is free software: you can
  8.     redistribute it and/or modify it under the terms of the GNU General
  9.     Public License as published by the Free Software Foundation, either
  10.     version 3 of the License, or (at your option) any later version.
  11.  
  12.     Stack Overflow Reputation Display is distributed in the hope that it
  13.     will be useful, but WITHOUT ANY WARRANTY; without even the implied
  14.     warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  15.     See the GNU General Public License for more details.
  16.  
  17.     You should have received a copy of the GNU General Public
  18.     License along with Stack Overflow Reputation Display. If not,
  19.     see <http://www.gnu.org/licenses/>.
  20. ##########################################################################*/
  21.  
  22. var SOAccount = function (init) {
  23.   if (typeof init == "object") {
  24.     for (var k in init)
  25.       this[k] = init[k];
  26.   } else if (typeof init == "string") {
  27.     this.config = init;
  28.   }
  29.  
  30.   this.observers = [];
  31.  
  32.   return this;
  33. };
  34.  
  35. SOAccount.prototype = {
  36.   _site:           null,
  37.   _user:           null,
  38.   sounds:          null,
  39.   dosounds:        false,
  40.   _updateinterval: 900,
  41.   clickaction:     "main",
  42.   debug:           false,
  43.  
  44.   intervaltimerid: null,
  45.  
  46.   clone: function () {
  47.     var c = new SOAccount(this);
  48.     delete c.intervaltimerid;
  49.     return c;
  50.   },
  51.  
  52.   wantspageloads: function () {
  53.     return !this.user;
  54.   },
  55.  
  56.   interfaces: {
  57.     sound:   Components.classes["@mozilla.org/sound;1"]
  58.                        .createInstance(Components.interfaces.nsISound),
  59.     console: Components.classes["@mozilla.org/consoleservice;1"]
  60.                        .getService(Components.interfaces.nsIConsoleService),
  61.     ios:     Components.classes["@mozilla.org/network/io-service;1"]
  62.                        .getService(Components.interfaces.nsIIOService),
  63.   },
  64.  
  65.   toString: function () {
  66.     return "[object SOAccount: " + this.config + "]";
  67.   },
  68.  
  69.   get config () {
  70.     var config = this.site.sitetag;
  71.  
  72.     config += ":";
  73.     if (this.user && this.user != SOAccount.prototype.user)
  74.     config += this.user;
  75.  
  76.     config += ":";
  77.     if (this.updateinterval && this.updateinterval != SOAccount.prototype.updateinterval)
  78.     config += this.updateinterval;
  79.  
  80.     config += ":";
  81.     if (this.clickaction && this.clickaction != SOAccount.prototype.clickaction)
  82.     config += this.clickaction;
  83.  
  84.     config += ":";
  85.     if (this.dosounds && this.dosounds != SOAccount.prototype.dosounds)
  86.     config += this.dosounds;
  87.  
  88.     config = config.replace(/:+$/, "");
  89.  
  90.     return config;
  91.   },
  92.  
  93.   set config (config) {
  94.     var parts = config.split(/:/);
  95.     var labels = [ "site", "user", "updateinterval", "clickaction", "dosounds", ]
  96.  
  97.     var fields = {};
  98.     if (parts[0]) fields.site           = new SOSite(parts[0]);
  99.     if (parts[1]) fields.user           = parts[1];
  100.     if (parts[2]) fields.updateinterval = parseInt(parts[2]);
  101.     if (parts[3]) fields.clickaction    = parts[3];
  102.     if (parts[4]) fields.dosounds       = (parts[4] == "true");
  103.  
  104.     for (var i=0; i<labels.length; i++)
  105.       if (labels[i] in fields) {
  106.         if (this[labels[i]] != fields[labels[i]])
  107.           this[labels[i]] = fields[labels[i]];
  108.       } else {
  109.         delete this[labels[i]];
  110.       }
  111.   },
  112.  
  113.   get datauri () {
  114.     return this.site.uri("data", this.user);
  115.   },
  116.  
  117.   get site () {
  118.     return this._site;
  119.   },
  120.  
  121.   set site (s) {
  122.     this._site = s;
  123.     this.user = null;
  124.   },
  125.  
  126.   get user () {
  127.     return this._user;
  128.   },
  129.  
  130.   set user (u) {
  131.     this._user = u;
  132.     delete this.info;
  133.   },
  134.  
  135.   get name () {
  136.     if (this.info)
  137.       return this.info.name;
  138.  
  139.     return null;
  140.   },
  141.  
  142.   get updateinterval () {
  143.     return this._updateinterval;
  144.   },
  145.  
  146.   set updateinterval (i) {
  147.     this._updateinterval = i;
  148.     if (this.intervaltimerid)
  149.       this.launchtimer();
  150.   },
  151.  
  152.   cleartimer: function () {
  153.     if (this.debug)
  154.       this.interfaces.console.logStringMessage("SOAccount clearing update inverval timer");
  155.     if (this.intervaltimerid) {
  156.       window.clearInterval(this.intervaltimerid);
  157.       delete this.intervaltimerid;
  158.     }
  159.   },
  160.  
  161.   launchtimer: function () {
  162.     if (this.user) {
  163.       var me = this;
  164.       this.cleartimer();
  165.       if (this.debug)
  166.         this.interfaces.console.logStringMessage("SOAccount setting update inverval to " + this.updateinterval + " seconds");
  167.       this.sendrequest();
  168.       this.intervaltimerid = window.setInterval(function () {
  169.                                                               me.sendrequest();
  170.                                                             },
  171.                                                 this.updateinterval * 1000);
  172.     }
  173.   },
  174.  
  175.   sendrequest: function () {
  176.     var datauri = this.datauri;
  177.     if (datauri) {
  178.       var me = this;
  179.       var req = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]  
  180.                           .createInstance(Components.interfaces.nsIXMLHttpRequest);  
  181.       if (this.debug)
  182.         this.interfaces.console.logStringMessage("SOAccount sending request (" + datauri + ")...");
  183.       req.onload = function (aEvt) { me.handleresponse(req.responseText); };
  184.  
  185.       req.open("GET", datauri, true);  
  186.       req.send(null);  
  187.     }
  188.   },
  189.  
  190.   addObserver: function (observer) {
  191.     this.observers.push(observer);
  192.   },
  193.  
  194.   removeObserver: function (observer) {
  195.     var newobservers = [];
  196.     for (var i=0; i<this.observers.length; i++)
  197.       if (this.observers[i] !== observer)
  198.         newobservers.push(this.observers[i]);
  199.     this.observers = newobservers;
  200.   },
  201.  
  202.   handleresponse: function (responsetext) {
  203.     if (this.debug)
  204.       this.interfaces.console.logStringMessage("SOAccount handling response...");
  205.  
  206.     var newinfo = this.site.extractinfo(responsetext);
  207.     if (!newinfo)
  208.       return;
  209.  
  210.     var currentinfo = this.info;
  211.     this.info = newinfo;
  212.     var change;
  213.  
  214.     if (currentinfo) {
  215.       if (this.debug)
  216.         this.interfaces.console.logStringMessage("SOAccount comparing new details with current...");
  217.       if (newinfo.reputation &&
  218.           "reputation" in currentinfo) {
  219.         if (newinfo.reputation > currentinfo.reputation) {
  220.           change = change || "up";
  221.         } else if (newinfo.reputation < currentinfo.reputation) {
  222.           change = change || "down";
  223.         }
  224.       }
  225.  
  226.       var badges = this.site.badges;
  227.       for (var i=0; i<badges.length; i++) {
  228.         var badge = badges[i];
  229.         if (newinfo[badge] &&
  230.           currentinfo[badge]) {
  231.           if (newinfo[badge] > currentinfo[badge]) {
  232.             change = change || "up";
  233.           } else if (newinfo[badge] < currentinfo[badge]) {
  234.             change = change || "down";
  235.           }
  236.         }
  237.       }
  238.  
  239.       if (change)
  240.         if (change == "up")
  241.           this.dosound("up");
  242.         else if (change == "down")
  243.           this.dosound("down");
  244.     }
  245.  
  246.     for (var i=0; i<this.observers.length; i++)
  247.       try {
  248.         this.observers[i].observe(this, "soaccount:scorechanged", change);
  249.       } finally {
  250.       }
  251.   },
  252.  
  253.   dosound: function (tag) {
  254.     if (this.debug)
  255.       this.interfaces.console.logStringMessage("SOAccount dosound() called for: " + tag);
  256.     if (this.dosounds && this.sounduris) {
  257.       if (tag in this.sounduris) {
  258.         if (this.debug)
  259.           this.interfaces.console.logStringMessage("SOAccount found sound: " + this.sounduris[tag]);
  260.         this.interfaces.sound.play(this.interfaces
  261.                                        .ios
  262.                                        .newURI(this.sounduris[tag], null, null)
  263.                                        .QueryInterface(Components.interfaces.nsIURL));
  264.       } else {
  265.         var scriptError = Components.classes["@mozilla.org/scripterror;1"]
  266.                                     .createInstance(Components.interfaces.nsIScriptError);
  267.         scriptError.init("SOAccount dosound() called with unknown sound \"" + tag + "\"",
  268.                          "chrome://sorepdisplay/content/soaccount.js",
  269.                          null,
  270.                          null, 
  271.                          null,
  272.                          nsIScriptError.errorFlag,
  273.                          null);
  274.         this.interfaces.console.logMessage(scriptError);
  275.       }
  276.     }
  277.   },
  278.  
  279.   pageload: function (doc) {
  280.     var user = this.site.finduser(doc);
  281.     if (user && user != this.user) {
  282.       this.user = user;
  283.       this.launchtimer();
  284.       return true;
  285.     }
  286.  
  287.     return false;
  288.   },
  289. };
  290.